﻿using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Documents;
using ff14bot;
using ff14bot.Behavior;
using ff14bot.Enums;
using ff14bot.Managers;
using ff14bot.Objects;
using System.Linq;
using TreeSharp;

using Action = TreeSharp.Action;

namespace Magitek.Helpers
{
    public static class PartyHelper
    {

        #region Variables
        public static BattleCharacter Healtarget;
        public static BattleCharacter Stoneskintarget;
        public static BattleCharacter Protecttarget;
        public static BattleCharacter Deadtarget;
        public static BattleCharacter Eyeforaneyetarget;
        public static BattleCharacter Covertarget;
        public static BattleCharacter Tetsudotarget;
        public static BattleCharacter Alliancehealtarget;
        public static BattleCharacter Dispeltarget;
        private static List<BattleCharacter> _healList;
        #endregion

        #region Behavior Tree
        public static Composite AcquireTargetInformation()
        {
            return new PrioritySelector(
                new Decorator(r => Core.Player.IsCasting, new ActionAlwaysSucceed()),

                BuildLists,

                new Action(r =>
                {

                    Healtarget = null;
                    Dispeltarget = null;
                    Alliancehealtarget = null;
                    Protecttarget = null;
                    Deadtarget = null;
                    Stoneskintarget = null;

                    return RunStatus.Failure;

                }),

                GetHealTarget,
                GetDispelTarget,
                GetAllianceHealTarget,
                GetProtectTarget,
                GetStoneskinTarget,
                GetDeadTarget

                );
        }

        #region Build Lists
        private static Composite BuildLists
        {
            get
            {
                return new Action(r =>
                {

                    _healList = new List<BattleCharacter>();
                    _healList.AddRange(PartyManager.VisibleMembers.Select(o => o.GameObject as BattleCharacter));
                    _healList = _healList.Where(u => Core.Player.Distance(u) <= 30 && u.InLineOfSight()).ToList();

                    return RunStatus.Failure;

                });
            }
        }
        #endregion
        #region Find Healer Targets
        private static Composite GetHealTarget
        {
            get
            {
                return new Decorator(r => PlayerIsHealer,
                    new Action(r =>
                    {
                        Healtarget = (from battleCharacter in _healList
                                      orderby battleCharacter.CurrentHealthPercent ascending
                                      where battleCharacter.CurrentHealthPercent < 100 & battleCharacter.CurrentHealth > 1
                                      select battleCharacter).FirstOrDefault();

                        return RunStatus.Failure;
                    }));
            }
        }

        private static Composite GetDispelTarget
        {
            get
            {
                return new Decorator(r => Magitek.WindowSettings._dispeList.Count > 0, new Action(x =>
                {
                    foreach (var battleCharacter in _healList.Where(u => Actionmanager.CanCast("Esuna", u) || Actionmanager.CanCast("Leeches", u)))
                    {
                        foreach (Aura aura in battleCharacter.CharacterAuras)
                        {
                            if (Magitek.WindowSettings._dispeList.Contains(aura.Name))
                                Dispeltarget = battleCharacter;
                        }
                    }

                    return RunStatus.Failure;
                }));
            }
        }

        private static Composite GetAllianceHealTarget
        {
            get
            {
                return new Decorator(r => Magitek.WindowSettings.HealEveryone && PlayerIsHealer,
                    new Action(r =>
                    {
                        Alliancehealtarget = (from battleCharacter in GameObjectManager.GetObjectsOfType<BattleCharacter>().Where(u => !u.CanAttack && u.InLineOfSight() && u.Distance(Core.Player) <= 30)
                                              orderby battleCharacter.CurrentHealthPercent ascending
                                              where battleCharacter.CurrentHealthPercent < 100 & battleCharacter.CurrentHealth > 1
                                              select battleCharacter).FirstOrDefault();

                        return RunStatus.Failure;
                    }));
            }
        }

        private static Composite GetProtectTarget
        {
            get
            {
                return new Decorator(r => (Magitek.WindowSettings.ScholarProtectOOC || Magitek.WindowSettings.WhiteMageProtectOOC) && PlayerIsHealer,
                        new Action(r =>
                        {
                            Protecttarget = (from battleCharacter in _healList
                                             where !battleCharacter.HasAura("Protect")
                                             where battleCharacter.CurrentJob != ClassJobType.Adventurer
                                             select battleCharacter).FirstOrDefault();

                            return RunStatus.Failure;
                        }));
            }
        }

        private static Composite GetStoneskinTarget
        {
            get
            {
                return new Decorator(r => Stoneskintarget == null && (Magitek.WindowSettings.ScholarStoneskinOOC || Magitek.WindowSettings.WhiteMageStoneskinOOC) && PlayerIsHealer,
                        new Action(r =>
                        {
                            Stoneskintarget = (from battleCharacter in _healList
                                               where !battleCharacter.HasAura("Stoneskin")
                                               select battleCharacter).FirstOrDefault();

                            return RunStatus.Failure;
                        }));
            }
        }

        private static Composite GetDeadTarget
        {
            get
            {
                return new Decorator(r => Deadtarget == null && PlayerIsHealer,
                    new Action(r =>
                    {
                        Deadtarget = (from battleCharacter in _healList
                                      orderby battleCharacter.CurrentHealthPercent ascending
                                      where battleCharacter.Status == CharacterStatus.Dead || battleCharacter.CurrentHealth == 0
                                      where Actionmanager.CanCast("Resurrection", battleCharacter) || Actionmanager.CanCast("Raise", battleCharacter)
                                      select battleCharacter).FirstOrDefault();

                        return RunStatus.Failure;
                    }));
            }
        }
        #endregion
        #endregion
        #region Find Targets
        #endregion
        #region Helpers
        private static bool PlayerIsHealer
        {
            get
            {
                return (Core.Player.CurrentJob == ClassJobType.WhiteMage ||
                        Core.Player.CurrentJob == ClassJobType.Scholar ||
                        Core.Player.CurrentJob == ClassJobType.Conjurer ||
                        Core.Player.CurrentJob == ClassJobType.Arcanist);
            }
        }
        private static bool PlayerIsTank
        {
            get
            {
                return (Core.Player.CurrentJob == ClassJobType.Marauder ||
                        Core.Player.CurrentJob == ClassJobType.Paladin ||
                        Core.Player.CurrentJob == ClassJobType.Gladiator ||
                        Core.Player.CurrentJob == ClassJobType.Warrior);
            }
        }
        public static bool IsTank(BattleCharacter p)
        {
            if (p.CurrentJob == ClassJobType.Warrior || p.CurrentJob == ClassJobType.Paladin || p.CurrentJob == ClassJobType.Gladiator || p.CurrentJob == ClassJobType.Marauder)
                return true;

            return false;
        }
        public static int PartyMembersNeedingHeals(int hp, int distance)
        {
            return PartyManager.VisibleMembers.Count(u => (u.GameObject as BattleCharacter).IsAlive && u.GameObject.Location.Distance(Core.Player.Location) < distance && (u.GameObject as BattleCharacter).CurrentHealthPercent < hp);
        }
        public static int PartyMembersNeedingHealsPet(int hp)
        {
            return PartyManager.VisibleMembers.Count(u => (u.GameObject as BattleCharacter).IsAlive && u.GameObject.Location.Distance(Core.Player.Pet.Location) < 15 && (u.GameObject as BattleCharacter).CurrentHealthPercent < hp);
        }
        public static int PartyMembersNeedingHealsMedicaII(int hp)
        {
            return PartyManager.VisibleMembers.Count(u => !u.GameObject.HasAura("Medica II", true) && (u.GameObject as BattleCharacter).IsAlive && u.GameObject.Location.Distance(Core.Player.Location) < 15 && (u.GameObject as BattleCharacter).CurrentHealthPercent < hp);
        }
        public static int PeopleNeedingHealsAroundTarget(int hp, BattleCharacter target)
        {
            return PartyManager.VisibleMembers.Count(u => (u.GameObject as BattleCharacter).IsAlive && u.GameObject.Location.Distance(target.Location) < 6 && (u.GameObject as BattleCharacter).CurrentHealthPercent < hp);
        }
        #endregion
    }
}
